/*	
*	File: udp-packet.h
*	Date: 2011/11/08
*	User: Ronmaru
*	Desctiption: rip packet class
*/

#include "pcraft-tool.h"

#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <string>
#include <istream>
#include <iostream>
#include <ostream>

//using boost::asio::ip::udp;
using boost::asio::deadline_timer;
namespace posix_time = boost::posix_time;

class RIPpacket
{
public:

  RIPpacket(boost::asio::io_service& io_service, 
    IPV4header ipv4_header, 
    UDPheader icmp_header, UDPpseudoheader pseudo_header, RIPheader rip_header)
    : raw_resolver_(io_service), raw_socket_(io_service, raw::v4()), 
    udp_pseudo_header_(pseudo_header), udp_header_(icmp_header), ipv4_header_(ipv4_header), 
    rip_header_(rip_header), encapsulate_ip_(0)
  {
    raw::resolver::query query(raw::v4(), ipv4_header.GetDestinationAddress().to_string(), "");
    raw_destination_ = *raw_resolver_.resolve(query);

    raw_socket_.connect(raw_destination_);
    const ip_hdrincl opt_ip_hdrincl(1);
    raw_socket_.set_option(opt_ip_hdrincl);
  }

  void send()
  {
    boost::asio::streambuf request_buffer;
    std::ostream os(&request_buffer);
    std::string str("");
    ComputeChecksum(udp_header_, udp_pseudo_header_, str.begin(), str.end());
    os << ipv4_header_ << udp_header_ << rip_header_;

    raw_socket_.send(request_buffer.data());
  }

  int encapsulate_ip_;
  raw::resolver raw_resolver_;
  raw::endpoint raw_destination_;
  raw::socket raw_socket_;

  RIPheader rip_header_;
  UDPheader udp_header_;
  UDPpseudoheader udp_pseudo_header_;
  IPV4header ipv4_header_;
};